#include "stdafx.h"
#include <windows.h>
#include <tlhelp32.h>
#include <Psapi.h>

void PrintError(TCHAR* msg)
{
    _tprintf(TEXT("  Error %d (%s)\n"), GetLastError(), msg);
}

void PrintMemoryInfo(DWORD dwPID)
{
    HANDLE hProcess;
    PROCESS_MEMORY_COUNTERS_EX pmc;

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPID);
    if (NULL == hProcess) return;

    _tprintf(TEXT("\nMemory:  \n"));  

    if (GetProcessMemoryInfo(hProcess, (PROCESS_MEMORY_COUNTERS *) &pmc, sizeof(pmc)))
    {
        printf("  Working set size:       %d\n", pmc.WorkingSetSize);
        printf("  Peak working set size:  %d\n", pmc.PeakWorkingSetSize);
        printf("  Pagefile usage:         %d\n", pmc.PagefileUsage);
        printf("  Peak pagefile usage:    %d\n", pmc.PeakPagefileUsage);
    }

    CloseHandle(hProcess);
}

BOOL PrintDLLS(DWORD dwPID)
{
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
    MODULEENTRY32 me32;

    hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
	if(hModuleSnap == INVALID_HANDLE_VALUE)
    {
        PrintError(TEXT("CreateToolhelp32Snapshot"));
        return(FALSE);
    }

    me32.dwSize = sizeof(MODULEENTRY32);

	if(!Module32First(hModuleSnap, &me32))
    {
        PrintError(TEXT("Module32First"));  
        CloseHandle(hModuleSnap);           
        return(FALSE);
    }

    _tprintf(TEXT("  %s\n"), me32.szExePath);  

    _tprintf(TEXT("\nDLLS: \n"));
	if (Module32Next(hModuleSnap, &me32)) { // skip exe name
		int i = 1;
		do 
		{
			_tprintf(TEXT("  %d) %s\n"), i++, me32.szModule);
		} while(Module32Next(hModuleSnap, &me32));
	}
	
    CloseHandle(hModuleSnap);
    return(TRUE);
}

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if(hSnapshot == INVALID_HANDLE_VALUE)
    {
        PrintError(TEXT("CreateToolhelp32Snapshot"));
		return EXIT_FAILURE;
    }

    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(hSnapshot, &pe)) 
    {
        PrintError(TEXT("Process32First"));
        CloseHandle(hSnapshot);
        return EXIT_FAILURE;
    }

    do
    {
		_tprintf(TEXT("\n\n--------------------------------------------------------------\n"));
		_tprintf(TEXT("%s\n"), pe.szExeFile);
        PrintDLLS(pe.th32ProcessID);
        PrintMemoryInfo(pe.th32ProcessID);
    } while(Process32Next(hSnapshot, &pe));

	return EXIT_SUCCESS;
}